﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.ProgressBar;
using YArchitech.Revit;
using YJKRGeometry;

namespace HYCoordinate
{
	public class DrainMakerApplication
	{
		public static bool UseMessageTag
		{
			get
			{
				return DrainMakerApplication.m_buseMessageTag;
			}
			set
			{
				DrainMakerApplication.m_buseMessageTag = value;
			}
		}

		public bool IfManualStop
		{
			get
			{
				return this.m_bIfManualStop;
			}
			private set
			{
				this.m_bIfManualStop = value;
			}
		}

		public DrainMakerApplication(UIApplication ui_app, Document m_doc, int index)
		{
			this.m_nIndex = index;
			this.m_Uiapp = ui_app;
			this.m_doc = m_doc;
			this.m_ThisStack = new InputDataStack(m_doc);
			this.m_lstOutPutFamilyFilePath.Clear();
		}

		public void AddOnePoint(OneInputDataPacker input)
		{
			if (input != null)
			{
				this.m_ThisStack.AddOnePoint(input);
				return;
			}
			this.m_ThisStack.SetEnd(true);
		}

		public XYZ GetEndPointNow()
		{
			return this.m_ThisStack.GetEndPoint();
		}

		public void DeleteAllDetailCurves()
		{
			this.m_ThisStack.DeleteAllDetailCurves();
		}

		internal void DrawSlopeTag()
		{
			List<ThreeInputDataPacker> result = this.m_ThisStack.GetResult();
			if (result.Count == 0 && this.m_ThisStack.GetTwoInputDataPacker(0) != null)
			{
				TwoInputDataPakcer twoInputDataPacker = this.m_ThisStack.GetTwoInputDataPacker(0);
				XYZ point = twoInputDataPacker.GetPoint(0);
				XYZ point2 = twoInputDataPacker.GetPoint(1);
				SlopeTagMaker slopeTagMaker = new SlopeTagMaker(this.m_doc, twoInputDataPacker, Utiltiy.GetMidPoint(point, point2));
				slopeTagMaker.DrawTag();
				this.m_lstSlopeTagElment.AddRange(slopeTagMaker.ThislstElement);
				if (slopeTagMaker.ThisSlopData != null)
				{
					this.m_AllSlopDataInfo.Add(slopeTagMaker.ThisSlopData);
					return;
				}
			}
			else if (result.Count > 0)
			{
				XYZ point;
				XYZ point2;
				SlopeTagMaker slopeTagMaker;
				for (int i = 0; i < result.Count; i++)
				{
					point = result[i].GetLstBoundryCurvePacker()[0].GetPoint(0);
					point2 = result[i].GetLstBoundryCurvePacker()[0].GetPoint(1);
					slopeTagMaker = new SlopeTagMaker(this.m_doc, result[i].GetTwoInputData(0), Utiltiy.GetMidPoint(point, point2));
					this.AddSlopMakerValueToField(slopeTagMaker);
				}
				int index = result.Count - 1;
				point = result[index].GetLstBoundryCurvePacker()[result[index].GetLstBoundryCurvePacker().Count - 1].GetPoint(0);
				point2 = result[index].GetLstBoundryCurvePacker()[result[index].GetLstBoundryCurvePacker().Count - 1].GetPoint(1);
				slopeTagMaker = new SlopeTagMaker(this.m_doc, result[index].GetTwoInputData(1), Utiltiy.GetMidPoint(point, point2));
				this.AddSlopMakerValueToField(slopeTagMaker);
			}
		}

		public void SetFamilies(ref ProgressBarForm tempForm, IntPtr parentHandle)
		{
			FamilyCreater familyCreater = FamilyCreater.GetFamilyCreater();
			List<ThreeInputDataPacker> result = this.m_ThisStack.GetResult();
			new MyFamilyLoadOptions();
			ElementSet elementSet = new ElementSet();
			Group group = null;
			Transaction transaction = new Transaction(this.m_doc, "addFamily");
			if (result.Count + 1 > 1)
			{
				tempForm = new ProgressBarForm(result.Count + 1, ProgressBarStyle.Blocks, false);
				tempForm.SetNoneCancle();
				tempForm.SetMaxValue(result.Count + 1);
				tempForm.Show(new WindowHandle(parentHandle));
			}
			try
			{
				transaction.Start();
				for (int i = 0; i < result.Count; i++)
				{
					if (tempForm != null)
					{
						if (tempForm.IsDisposed)
						{
							this.IfManualStop = true;
							transaction.RollBack();
							return;
						}
						tempForm.RefreshProgressBar();
						if (tempForm.IsDisposed)
						{
							this.IfManualStop = true;
							transaction.RollBack();
							return;
						}
					}
					foreach (BoundryCurvePakcer boundryCurvePakcer in result[i].GetLstBoundryCurvePacker())
					{
						if (!this.useFamily(boundryCurvePakcer, elementSet))
						{
							this.m_lstOutPutFamilyFilePath.Add(familyCreater.SetResultData(this.m_Uiapp, boundryCurvePakcer, boundryCurvePakcer.Deep));
							this.m_lstRealStartPoints.Add(familyCreater.GetRealStartPoint());
							string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(this.m_lstOutPutFamilyFilePath[this.m_lstOutPutFamilyFilePath.Count - 1]);
							FamilySymbol familySymbol = null;
                            this.m_doc.LoadFamilySymbol(this.m_lstOutPutFamilyFilePath[this.m_lstOutPutFamilyFilePath.Count - 1], fileNameWithoutExtension, out familySymbol);
							familySymbol.Activate();
                            elementSet.Insert(this.m_doc.Create.NewFamilyInstance(this.m_lstRealStartPoints[this.m_lstRealStartPoints.Count - 1], familySymbol, (Autodesk.Revit.DB.Structure.StructuralType)3));
							File.Delete(this.m_lstOutPutFamilyFilePath[this.m_lstOutPutFamilyFilePath.Count - 1]);
							this.m_dDeep = boundryCurvePakcer.Deep;
						}
					}
				}
				BoundryCurvePakcer boundryCurvePakcer2 = null;
				if (result.Count == 0 && this.m_ThisStack.GetTwoInputDataPacker(0) != null)
				{
					TwoInputDataPakcer twoInputDataPacker = this.m_ThisStack.GetTwoInputDataPacker(0);
					double[] array = new double[]
					{
						twoInputDataPacker.GetParameters(1)[UseParameterEnum.Depth],
						twoInputDataPacker.GetParameters(1)[UseParameterEnum.Thickness],
						twoInputDataPacker.GetParameters(1)[UseParameterEnum.FlateWidth],
						(double)twoInputDataPacker.GetFamilyFileIndex(0)
					};
					double[] valueParams = new double[]
					{
						twoInputDataPacker.GetParameters(1)[UseParameterEnum.Depth],
						twoInputDataPacker.GetParameters(1)[UseParameterEnum.Thickness],
						twoInputDataPacker.GetParameters(1)[UseParameterEnum.FlateWidth],
						(double)twoInputDataPacker.GetFamilyFileIndex(0)
					};
					boundryCurvePakcer2 = new BoundryCurvePakcer(twoInputDataPacker.GetPoint(0), twoInputDataPacker.GetPoint(1), Utiltiy.GetNormalLineBoundryCurves(twoInputDataPacker.GetPoint(0), twoInputDataPacker.GetPoint(1), twoInputDataPacker.GetParameters(1)), false, valueParams);
					this.useFamily(boundryCurvePakcer2, elementSet);
					this.m_dDeep = boundryCurvePakcer2.Deep;
				}
				Line line = null;
				if (this.m_ThisStack.GetTwoInputDataPacker(0) != null)
				{
					line = this.m_ThisStack.GetTwoInputDataPacker(0).StartLine;
				}
				foreach (Element element in this.m_lstSlopeTagElment)
				{
					if (element != null)
					{
						elementSet.Insert(element);
					}
				}
				if (elementSet.Size > 0)
				{
					group = this.m_doc.CreatYJKGroup(elementSet);
				}
				transaction.Commit();
				if (group != null)
				{
					DrainBuryData.CreatSchema(this.m_doc, "43FEE925-0EBE-45D8-BA6F-72A4411E065A", "DrainBuryData");
					DrainBuryDataStruct drainBuryDataStruct = new DrainBuryDataStruct();
					List<string> collection = new List<string>();
					List<Line> list = new List<Line>();
					foreach (ThreeInputDataPacker threeInputDataPacker in result)
					{
						foreach (BoundryCurvePakcer boundryCurvePakcer3 in threeInputDataPacker.GetLstBoundryCurvePacker())
						{
							if (!boundryCurvePakcer3.IfCorner)
							{
								collection = new List<string>();
								list = new List<Line>();
								foreach (Curve curve in boundryCurvePakcer3.LstBoundryCurves)
								{
									list.Add(curve as Line);
								}
								if (DataSerializeDeserialize.LineToString(list, out collection))
								{
									drainBuryDataStruct.m_lstLineString.AddRange(collection);
								}
							}
						}
					}
					if (result.Count == 0 && boundryCurvePakcer2 != null)
					{
						collection = new List<string>();
						list = new List<Line>();
						foreach (Curve curve2 in boundryCurvePakcer2.LstBoundryCurves)
						{
							list.Add(curve2 as Line);
						}
						if (DataSerializeDeserialize.LineToString(list, out collection))
						{
							drainBuryDataStruct.m_lstLineString.AddRange(collection);
						}
					}
					DataSerializeDeserialize.PointToString((group.Location as LocationPoint).Point, out drainBuryDataStruct.m_strLocationPoint);
					drainBuryDataStruct.m_strDeep = this.m_dDeep.ToString();
					drainBuryDataStruct.m_strGroup = this.m_nIndex.ToString();
					DataSerializeDeserialize.PointToString(group.get_BoundingBox(null).Max, out drainBuryDataStruct.m_strMaxPoint);
					DataSerializeDeserialize.PointToString(group.get_BoundingBox(null).Min, out drainBuryDataStruct.m_strMinPoint);
					foreach (SlopDataInfo slopDataInfo in this.m_AllSlopDataInfo)
					{
						drainBuryDataStruct.m_lstSlopeString.Add(slopDataInfo.ToString());
					}
					if (null != line)
					{
						DataSerializeDeserialize.LineToString(line, out drainBuryDataStruct.m_strStartLine);
					}
					DrainBuryData.BuryDataToDrain("43FEE925-0EBE-45D8-BA6F-72A4411E065A", group, "DrainBuryData", drainBuryDataStruct);
				}
			}
			catch (Exception)
			{
				if (transaction.HasStarted())
				{
					transaction.RollBack();
				}
			}
			finally
			{
				if (tempForm != null && !tempForm.IsDisposed)
				{
					tempForm.Dispose();
				}
			}
		}

		private void AddSlopMakerValueToField(SlopeTagMaker tempSlopeMaker)
		{
			if (tempSlopeMaker != null)
			{
				tempSlopeMaker.DrawTag();
				this.m_lstSlopeTagElment.AddRange(tempSlopeMaker.ThislstElement);
				if (tempSlopeMaker.ThisSlopData != null)
				{
					this.m_AllSlopDataInfo.Add(tempSlopeMaker.ThisSlopData);
				}
			}
		}

		private bool useFamily(BoundryCurvePakcer input, ElementSet familySet)
		{
			if (input.IfCorner)
			{
				return false;
			}
			SubTransaction subTransaction = new SubTransaction(this.m_doc);
			subTransaction.Start();
			string text = StaticRescource.StrArrayUseFamilyNames[input.FamilyFileIndex];
			FamilySymbol familySymbol = null;
			if (!this.ifHasUseFamily(text, out familySymbol))
			{
				string text2 = StaticRescource.StrUseFamilyPath + text + StaticRescource.StrRfa;
				this.m_doc.LoadFamilySymbol(text2, text, out familySymbol);
			}
			if (familySymbol != null)
			{
				familySymbol.Activate();
                FamilyInstance familyInstance = this.m_doc.Create.NewFamilyInstance(input.GetPoint(0), familySymbol, (Autodesk.Revit.DB.Structure.StructuralType)3);
				Parameter parameter = familyInstance.GetParametersByName(StaticRescource.StrLength)[0];
				double num = input.GetPoint(0).DistanceTo(input.GetPoint(1));
				parameter.Set(num);
				familyInstance.GetParametersByName(StaticRescource.StrFlateWidth)[0].Set(input.FlateWidth);
				familyInstance.GetParametersByName(StaticRescource.StrThickness)[0].Set(input.Thickness);
				Parameter parameter2 = familyInstance.GetParametersByName(StaticRescource.StrDepth)[0];
				double num2 = input.Deep - input.Thickness;
				parameter2.Set(num2);
				Line line = Line.CreateBound(input.GetPoint(0), input.GetPoint(1));
				Line line2 = Line.CreateUnbound(input.GetPoint(0), new XYZ(1.0, 0.0, 0.0));
				double num3;
				if (input.GetPoint(1).Y > input.GetPoint(0).Y)
				{
					num3 = line.Direction.AngleTo(line2.Direction);
				}
				else
				{
					num3 = line.Direction.AngleTo(line2.Direction);
					num3 = -num3;
				}
				Line line3 = Line.CreateUnbound(input.GetPoint(0), StaticRescource.GetXYPlaneNorme(0));
				ElementTransformUtils.RotateElement(this.m_doc, familyInstance.Id, line3, num3);
				familySet.Insert(familyInstance);
			}
			subTransaction.Commit();
			return true;
		}

		private bool ifHasUseFamily(string familyName, out FamilySymbol outFamilySymobl)
		{
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(FamilySymbol));
			foreach (Element element in new FilteredElementCollector(this.m_doc).WherePasses(elementClassFilter).ToElements())
			{
				if (element.Name.Equals(familyName))
				{
					outFamilySymobl = (element as FamilySymbol);
					return true;
				}
			}
			outFamilySymobl = null;
			return false;
		}

		private static bool m_buseMessageTag = true;

		private Document m_doc;

		private UIApplication m_Uiapp;

		private InputDataStack m_ThisStack;

		private List<string> m_lstOutPutFamilyFilePath = new List<string>();

		private List<XYZ> m_lstRealStartPoints = new List<XYZ>();

		private bool m_bIfManualStop;

		private int m_nIndex;

		private double m_dDeep;

		private List<Element> m_lstSlopeTagElment = new List<Element>();

		private List<SlopDataInfo> m_AllSlopDataInfo = new List<SlopDataInfo>();
	}
}
